# 检测异动,方便打板
import time
from datetime import datetime

import akshare as ak
import pandas as pd
import requests

from core.Constants import UNIT_WAN
from scripts.feishu_util import send_feishu_text
from scripts.single.stock_zh_a_hist import get_one_stock
from util.stock_util import is_main_board, is_limit_up

# ak.stock_changes_em()


def stock_changes_em(symbol: str = "大笔买入") -> pd.DataFrame:
    """
    东方财富-行情中心-盘口异动
    https://quote.eastmoney.com/changes/
    :param symbol: choice of {'火箭发射', '快速反弹', '大笔买入', '封涨停板', '打开跌停板', '有大买盘',
    '竞价上涨', '高开5日线', '向上缺口', '60日新高', '60日大幅上涨', '加速下跌', '高台跳水',
    '大笔卖出', '封跌停板', '打开涨停板', '有大卖盘', '竞价下跌', '低开5日线', '向下缺口', '60日新低', '60日大幅下跌'}
    :type symbol: str
    :return: 盘口异动
    :rtype: pandas.DataFrame
    """
    url = "https://push2ex.eastmoney.com/getAllStockChanges"
    symbol_map = {
        "火箭发射": "8201",
        "快速反弹": "8202",
        "大笔买入": "8193",
        "封涨停板": "4",
        "打开跌停板": "32",
        "有大买盘": "64",
        "竞价上涨": "8207",
        "高开5日线": "8209",
        "向上缺口": "8211",
        "60日新高": "8213",
        "60日大幅上涨": "8215",
        "加速下跌": "8204",
        "高台跳水": "8203",
        "大笔卖出": "8194",
        "封跌停板": "8",
        "打开涨停板": "16",
        "有大卖盘": "128",
        "竞价下跌": "8208",
        "低开5日线": "8210",
        "向下缺口": "8212",
        "60日新低": "8214",
        "60日大幅下跌": "8216",
    }
    reversed_symbol_map = {v: k for k, v in symbol_map.items()}
    params = {
        "type": symbol_map[symbol],
        "pageindex": "0",
        "pagesize": "10",
        "ut": "7eea3edcaed734bea9cbfc24409ed989",
        "dpt": "wzchanges",
    }
    r = requests.get(url, params=params)
    data_json = r.json()
    temp_df = pd.DataFrame(data_json["data"]["allstock"])
    temp_df["tm"] = pd.to_datetime(temp_df["tm"], format="%H%M%S").dt.time
    temp_df.columns = [
        "时间",
        "代码",
        "_",
        "名称",
        "板块",
        "相关信息",
    ]
    temp_df = temp_df[
        [
            "时间",
            "代码",
            "名称",
            "板块",
            "相关信息",
        ]
    ]
    # 示例：按逗号分隔成4列
    temp_df[['手数', '均价', 'a', '金额']] = temp_df['相关信息'].str.split(',', expand=True)
    # 批量转换为数字（浮点数）
    temp_df[['手数', '均价', 'a', '金额']] = temp_df[['手数', '均价', 'a', '金额']].apply(pd.to_numeric,
                                                                                          errors='coerce')
    # 方法1：直接指定列名列表删除（返回新DataFrame）
    temp_df = temp_df.drop(columns=['相关信息', '板块', 'a'])
    temp_df['金额'] = temp_df['金额'] / UNIT_WAN
    return temp_df


class Stock_changes_big_money:
    def __init__(self):
        self.prev_filtered_stocks = None
        self.cache = {}
        self.today_str = datetime.today().strftime('%Y%m%d')
        self.has_zhangting_15 = []

    def job(self):
        dbmr = stock_changes_em(symbol="大笔买入")

        # 过滤主板股票且最新价<100元
        filtered_stocks = dbmr[
            (dbmr['代码'].apply(is_main_board)) &  # 主板
            (dbmr['金额'] > 500) &  #
            (dbmr['均价'] < 100)
            ]

        self.send_msg(filtered_stocks)

        self.prev_filtered_stocks = dbmr

    def run_every(self, interval=5):
        while True:
            # 获取当前时间（北京时间，UTC+8）
            now = datetime.now()  # 或 datetime.utcnow() + timedelta(hours=8)
            # 格式化为字符串
            formatted_time = now.strftime("%H:%M:%S")  # 2025-08-04 21:33:43
            print("运行时间 ：" + formatted_time)

            self.job()
            time.sleep(interval)

    def send_msg(self, df_new):
        df_old = self.prev_filtered_stocks
        if df_old is None:
            added_data = df_new
        else:
            added_data = df_new[~df_new['时间'].isin(df_old['时间'])]
        if len(added_data) == 0:
            return

        for idx, row in added_data.iterrows():
            code = row['代码']
            jin_e = row['金额']  # 万为单位
            price = row['均价']
            if code in self.cache:
                stock_data = self.cache[code]
            else:
                stock_data = get_one_stock(code)
                self.cache[code] = stock_data
            has_zhangting = False
            if code in self.has_zhangting_15:
                has_zhangting = True
                self.has_zhangting_15.append(code)
            else:
                last_10_rows = stock_data.tail(10)
                for index, last_row in last_10_rows.iterrows():
                    zhang_percent = last_row['涨跌幅']
                    if is_limit_up(code, zhang_percent):
                        has_zhangting = True
                        self.has_zhangting_15.append(code)
                        break
            last_row = stock_data.iloc[-1]
            # 当前单子占5日成交额的千分比
            cjl_percent = (jin_e * 1e4 * 1e3 / (last_row['CJ5'] * 1e8)).round(2)
            json_str = row.to_json(force_ascii=False, orient='index')
            if has_zhangting:
                json_str = " 10日有涨停 " + json_str
            if price / last_row['MA30'] < 1.05:
                json_str = "price/MA30小于1.05" + json_str
            if int(jin_e) > 1000:
                json_str = "✅✅✅" + json_str



            json_str = '成交额MA5占比：' + str(cjl_percent) + '‰  ' + json_str
            print(json_str)
            send_feishu_text(json_str)
        # send_msg_2_ding(json_str)


if __name__ == '__main__':
    Stock_changes_big_money().run_every(15)
